//
// Created by ziya on 22-8-20.
//

#include "../../include/common.h"
#include "../../include/core/coroutine.h"
#include "../../include/core/sched.h"

coroutine_t * coroutines[TASK_SIZE] = {0};

extern coroutine_t* current_coroutine;

static int find_free_zid() {
    for (int i = 0; i < TASK_SIZE; ++i) {
        if (NULL == coroutines[i]) {
            return i;
        }
    }

    return -1;
}

uint coroutine_create(OUT uint* pzid, coroutine_fun_t entry, char* name, int priority) {
    int zid;
    coroutine_t* coroutine;

    // 找到可用的协程ID
    zid = find_free_zid();
    if (-1 == zid) {
        ERROR_PRINT("协程数量达到最大值\n");
        return -1;
    }

    // 创建微内核实例
    coroutine = malloc(sizeof(coroutine_t));
    if (NULL == coroutine) {
        ERROR_PRINT("malloc fail\n");
        return -1;
    }

    coroutine->state = COROUTINE_INIT;
    coroutine->zid = zid;
    coroutine->fun = entry;
    coroutine->priority = coroutine->counter = priority;
    coroutine->esp3 = malloc(getpagesize()) + getpagesize();

    memcpy(coroutine->name, name, strlen(name));

    // 将准备好的微内核写入调度数组
    coroutines[zid] = coroutine;

    if (NULL != pzid) {
        *pzid = zid;
    }

    // 更新协程状态为ready，表示可调度
    coroutine->state = COROUTINE_READY;

    return 0;
}

void coroutine_exit() {
    if (NULL == current_coroutine) {
        ERROR_PRINT("current_minithread == NULL\n");
        return;
    }

    for (int i = 0; i < TASK_SIZE; ++i) {
        coroutine_t* tmp = coroutines[i];

        if(NULL == tmp) continue;
        if (COROUTINE_RUNNING != tmp->state) continue;

        coroutines[i] = NULL;

        INFO_PRINT("current_minithread exit: %s\n", tmp->name);

        free(tmp);
    }

    sched();
}